/* 
 * File:   Logger.h
 * Author: ekto
 *
 * Created on 11 Μάρτιος 2011, 8:21 μμ
 */

#ifndef LOGGER_H
#define	LOGGER_H

#include "LogFileStream.h"
#include "Singleton.h"

//macros used for easier user of logger
//use them instead of Logger::GetInstance().Log(Logger::CHANNEL_MAIN,LogFileStream::LEVEL_NOTE)
//ex. LOGNOTE << "Note";
#define LOG(x,y) Logger::GetInstance()->Get(x).Log(y)
#define LOGNOTE Logger::GetInstance()->Get().Log()
#define LOGERROR Logger::GetInstance()->Get().Log(LogFileStream::LEVEL_ERROR)
#define LOGWARNING Logger::GetInstance()->Get().Log(LogFileStream::LEVEL_WARNING)

//macro used to get file and line number
//DEBUG must be defined 
#ifdef DEBUG
#define SOURCE __FILE__ << " : (" <<__LINE__ << ")"
#else
#define SOURCE
#endif

//macro used to print out the time and date of the build
#define BUILD_TIME __DATE__ <<" : " << __TIME__

//macro used to print out the actuall literal of an expresion and its value
//ex. ECHO_EXPR(foo[i].bar()) foo[i].bar() = 25
#define ECHO_EXP(x) #x " = " << x << " "

//macro used as the above but prints a different literal than the expr
#define TAG_EXP(x,y) #x " = " << y << " "

/**
 * Use this class to log events and values. Everything logged using this class will be written to files, one per channel.
 * One example of use could be:
 * Logger::GetInstance().Log(Logger::CHANNEL_MAIN,LogFileStream::LEVEL_NOTE) << "lollercoaster";
 */
class Logger
{
    SingletonClassCustomConst(Logger)
public:

    /**
     * The ids of the channels.
     */
    enum Channel
    {
        CHANNEL_MAIN,
        CHANNEL_LOADING,
        CHANNEL_AUDIO,
        CHANNEL_GRAPHICS,
        CHANNEL_SCRIPTING,
        CHANNEL_PHYSICS,
        /**
         * The total number of channels.
         */
        CHANNEL_COUNT
    };

    ~Logger();

    /**
     * Returns the specified channel stream.
     * @param channel The id of the channel. Use the Logger::CHANNEL_* enum values.
     * @return The requested channel's LogFileStream.
     */
    LogFileStream& Get(int channel = CHANNEL_MAIN);

    /**
     * Deletes all content of the specified channel.
     * @param channel The id of the channel to clear. Use the Logger::CHANNEL_* enum values.
     */
    void Clear(int channel);
private:
    /**
     * The channel streams.
     */
    LogFileStream channels_[CHANNEL_COUNT];

    /**
     * The names of the channels.
     */
    char* channelNames_[CHANNEL_COUNT];
};

#endif	/* LOGGER_H */